home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / xlib05.zip / XCIRCLE.ASM < prev    next >
Assembly Source File  |  1993-08-26  |  17KB  |  711 lines

  1. ;-----------------------------------------------------------------------
  2. ;
  3. ; MODULE XCIRCLE
  4. ;
  5. ;   This module was written by Matthew MacKenzie
  6. ;   matm@eng.umd.edu
  7. ;
  8. ; Circles, full and empty.
  9. ;
  10. ; Compile with Tasm.
  11. ; C callable.
  12. ;
  13. ; ****** XLIB - Mode X graphics library                ****************
  14. ; ******                                               ****************
  15. ;
  16. ; egg@dstos3.dsto.gov.au
  17. ; teg@bart.dsto.gov.au
  18. ;-----------------------------------------------------------------------
  19.  
  20. include xlib.inc
  21. include xcircle.inc
  22.  
  23. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  24. ; _x_circle
  25. ;
  26. ; Draw a circle.
  27. ;
  28. ; C near-callable as:
  29. ; int x_circle (WORD Left, WORD Top, WORD Diameter,
  30. ;                WORD Color, WORD ScreenOffs);
  31. ;
  32. ; No clipping is performed.
  33. ;
  34. ; ax, bx, cx, and dx bite the dust, as Homer would say.
  35.  
  36. ; we plot into eight arcs at once:
  37. ;      4 0
  38. ;    6 \|/ 2
  39. ;     --*--
  40. ;    7 /|\ 3
  41. ;      5 1
  42. ;
  43. ; 0, 1, 4, and 5 are considered x-major; the rest, y-major.
  44. ;
  45. ; The x-major plots grow out from the top and bottom of the circle,
  46. ; while the y-major plots start at the left and right edges.
  47.  
  48.     .data
  49.  
  50.     align 2
  51.  
  52. ColumnMask      db      011h,022h,044h,088h
  53.  
  54.     .code
  55.  
  56.     public _x_circle
  57.     align   2
  58. _x_circle proc
  59. ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word
  60. LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error:word=LocalStk
  61. ; Tasm 1.0 does not allow the \ line continuation
  62. ;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \
  63. ;      offset4:word, offset5:word, offset6:word, offset7:word, \
  64. ;      mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \
  65. ;      shrunk_radius:word, diameter_even:word, error:word=LocalStk
  66.  
  67.     push bp
  68.     mov  bp, sp
  69.     sub  sp, LocalStk
  70.     push si
  71.     push di
  72.     push ds
  73.  
  74. ; find starting locations of plots 2, 3, 6, and 7
  75.     mov di, _ScrnLogicalByteWidth
  76.     xor dx, dx
  77.  
  78.     mov ax, Diameter    ; find vertical midpoint
  79.     dec ax
  80.     shr ax, 1
  81.     adc dx, 0           ; remember if it's rounded
  82.     mov shrunk_radius, ax ; radius, rounded down for adding
  83.     mov diameter_even, dx ; (diameter - 1) & 1, effectively
  84.     add ax, Top
  85.     mul di              ; vertical midpoint in bytes
  86.     add ax, ScreenOffs
  87.  
  88.     mov bx, Left
  89.     mov cx, bx          ; save for later
  90.     mov si, bx
  91.     shr si, 2
  92.     add si, ax
  93.     mov offset6, si
  94.     and bx, 3           ; column of left side
  95.     mov bl, ColumnMask[bx]
  96.     mov mask6n7, bx
  97.  
  98.     add cx, Diameter
  99.     dec cx
  100.     mov bx, cx
  101.     shr cx, 2
  102.     add cx, ax
  103.     mov offset2, cx
  104.     and bx, 3           ; column of right side
  105.     mov bl, ColumnMask[bx]
  106.     mov mask2n3, bx
  107.  
  108.     cmp diameter_even, 1
  109.     jne @@MiddlePlotsOverlap
  110.     add si, di
  111.     add cx, di
  112. @@MiddlePlotsOverlap:
  113.     mov offset7, si
  114.     mov offset3, cx
  115.  
  116. ; starting locations of 0, 1, 4, and 5
  117.     mov bx, Left
  118.     add bx, shrunk_radius ; find horizontal midpoint
  119.  
  120.     mov ax, Top         ; top in bytes
  121.     mul di
  122.     add ax, ScreenOffs
  123.     mov si, ax
  124.  
  125.     mov ax, Diameter    ; bottom in bytes
  126.     dec ax
  127.     mul di
  128.     add ax, si
  129.  
  130.     mov di, bx          ; horizontal midpoint in bytes
  131.     shr di, 2
  132.     add si, di             ; top midpoint in bytes
  133.     mov offset4, si
  134.     add di, ax             ; bottom midpoint in bytes
  135.     mov offset5, di
  136.     and bx, 3           ; column of horizontal midpoint
  137.     mov bl, ColumnMask[bx]
  138.     mov mask4n5, bx
  139.  
  140.     cmp diameter_even, 1
  141.     jne @@TopAndBottomPlotsOverlap
  142.     rol bl, 1
  143.     jnc @@TopAndBottomPlotsOverlap
  144.     inc si
  145.     inc di
  146. @@TopAndBottomPlotsOverlap:
  147.     mov offset0, si
  148.     mov offset1, di
  149.     mov mask0n1, bx
  150.  
  151. ; we've got our eight plots in their starting positions, so
  152. ; it's time to sort out the registers
  153.     mov bx, _ScrnLogicalByteWidth
  154.  
  155.     mov dx, SCREEN_SEG
  156.     mov ds, dx
  157.  
  158.     mov dx, SC_INDEX    ; set VGA to accept column masks
  159.     mov al, MAP_MASK
  160.     out dx, al
  161.     inc dx              ; gun the engine...
  162.  
  163.     mov si, Diameter    ; initial y is radius -- 2 #s per pixel
  164.     inc si
  165.  
  166.     mov cx, si
  167.     neg cx
  168.     add cx, 2
  169.     mov error, cx        ; error = -y + one pixel since we're a step ahead
  170.  
  171.     xor cx, cx          ; initial x = 0
  172.     mov ah, byte ptr Color
  173.     jmp @@CircleCalc    ; let's actually put something on the screen!
  174.  
  175. ; move the x-major plots horizontally and the y-major plots vertically
  176. @@NoAdvance:
  177.     mov al, byte ptr mask0n1
  178.     out dx, al
  179.     mov di, offset0     ; plot 0
  180.     mov [di], ah
  181.     rol al, 1           ; advance 0 right
  182.     mov byte ptr mask0n1, al
  183.     adc di, 0
  184.     mov offset0, di
  185.     mov di, offset1
  186.     mov [di], ah        ; plot 1
  187.     ror al, 1           ; what was that bit again?
  188.     adc di, 0           ; advance 1 right
  189.     mov offset1, di
  190.  
  191.     mov al, byte ptr mask2n3
  192.     out dx, al
  193.     mov di, offset2
  194.     mov [di], ah        ; plot 2
  195.     sub di, bx          ; advance 2 up
  196.     mov offset2, di
  197.     mov di, offset3
  198.     mov [di], ah        ; plot 3
  199.     add di, bx          ; advance 3 down
  200.     mov offset3, di
  201.  
  202.     mov al, byte ptr mask4n5
  203.     out dx, al
  204.     mov di, offset4
  205.     mov [di], ah
  206.     ror al, 1
  207.     mov byte ptr mask4n5, al
  208.     sbb di, 0
  209.     mov offset4, di
  210.     mov di, offset5
  211.     mov [di], ah
  212.     rol al, 1
  213.     sbb di, 0
  214.     mov offset5, di
  215.  
  216.     mov al, byte ptr mask6n7
  217.     out dx, al
  218.     mov di, offset6
  219.     mov [di], ah
  220.     sub di, bx
  221.     mov offset6, di
  222.     mov di, offset7
  223.     mov [di], ah
  224.     add di, bx
  225.     mov offset7, di
  226.  
  227.     jmp @@CircleCalc
  228.  
  229. ; move all plots diagonally
  230. @@Advance:
  231.     mov al, byte ptr mask0n1
  232.     out dx, al
  233.     mov di, offset0
  234.     mov [di], ah        ; plot 0
  235.     rol al, 1           ; advance 0 right and down
  236.     mov byte ptr mask0n1, al
  237.     adc di, bx
  238.     mov offset0, di
  239.     mov di, offset1
  240.     mov [di], ah        ; plot 1
  241.     ror al, 1           ; what was that bit again?
  242.     adc di, 0           ; advance 1 right and up
  243.     sub di, bx
  244.     mov offset1, di
  245.  
  246.     mov al, byte ptr mask2n3
  247.     out dx, al
  248.     mov di, offset2
  249.     mov [di], ah        ; plot 2
  250.     ror al, 1           ; advance 2 up and left
  251.     mov byte ptr mask2n3, al
  252.     sbb di, bx
  253.     mov offset2, di
  254.     mov di, offset3
  255.     mov [di], ah        ; plot 3
  256.     rol al, 1
  257.     sbb di, 0           ; advance 3 down and left
  258.     add di, bx
  259.     mov offset3, di
  260.  
  261.     mov al, byte ptr mask4n5
  262.     out dx, al
  263.     mov di, offset4
  264.     mov [di], ah
  265.     ror al, 1
  266.     mov byte ptr mask4n5, al
  267.     sbb di, 0
  268.     add di, bx
  269.     mov offset4, di
  270.     mov di, offset5
  271.     mov [di], ah
  272.     rol al, 1
  273.     sbb di, bx
  274.     mov offset5, di
  275.  
  276.     mov al, byte ptr mask6n7
  277.     out dx, al
  278.     mov di, offset6
  279.     mov [di], ah
  280.     rol al, 1
  281.     mov byte ptr mask6n7, al
  282.     adc di, 0
  283.     sub di, bx
  284.     mov offset6, di
  285.     mov di, offset7
  286.     mov [di], ah
  287.     ror al, 1
  288.     adc di, bx
  289.     mov offset7, di
  290.  
  291. ; do you realize the entire function has been set up for this little jot?
  292. ; keep in mind that radii values are 2 per pixel
  293. @@CircleCalc:
  294.     add cx, 2           ; x += 1
  295.     mov di, error
  296.     add di, cx          ; error += (2 * x) + 1
  297.     inc di
  298.     jl @@CircleNoError
  299.     cmp cx, si          ; x > y?
  300.     ja @@FleeFlyFlowFum
  301.     sub si, 2           ; y -= 1
  302.     sub di, si          ; error -= (2 * y)
  303.     mov error, di
  304.     jmp @@Advance
  305. @@CircleNoError:
  306.     mov error, di
  307.     jmp @@NoAdvance
  308.  
  309. @@FleeFlyFlowFum:
  310.     pop ds
  311.     pop di
  312.     pop si
  313.     mov sp,bp
  314.     pop bp
  315.  
  316.     ret
  317.  
  318. _x_circle endp
  319.  
  320.  
  321. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  322. ; _x_filled_circle
  323. ;
  324. ; Draw a disc.
  325. ;
  326. ; C near-callable as:
  327. ; int x_filled_circle (WORD Left, WORD Top, WORD Diameter,
  328. ;                      WORD Color, WORD ScreenOffs);
  329. ;
  330. ; No clipping is performed.
  331. ;
  332. ; ax, bx, cx, dx, and es bite the dust, as Homer would say.
  333. ; DF is set to 0 (strings go forward).
  334.  
  335.     .data
  336.  
  337.     align 2
  338.  
  339. ; the only entries of these tables which are used are positions
  340. ; 1, 2, 4, and 8
  341. LeftMaskTable   db      0, 0ffh, 0eeh, 0, 0cch, 0, 0, 0, 088h
  342. RightMaskTable  db        0, 011h, 033h, 0, 077h, 0, 0, 0, 0ffh
  343.  
  344.     .code
  345.  
  346.     public _x_filled_circle
  347.     align   2
  348. _x_filled_circle proc
  349. ARG Left:word, Top:word, Diameter:word, Color:word, ScreenOffs:word
  350. ; Tasm 1.0 does not allow the \ line continuation
  351. ;LOCAL offset0:word, offset1:word, offset2:word, offset3:word, \
  352. ;      offset4:word, offset5:word, offset6:word, offset7:word, \
  353. ;      mask0n1:word, mask2n3:word, mask4n5:word, mask6n7:word, \
  354. ;      shrunk_radius:word, diameter_even:word, error:word, \
  355. ;      jump_vector:word=LocalStk
  356. LOCAL offset0,offset1,offset2,offset3,offset4,offset5,offset6,offset7,mask0n1,mask2n3,mask4n5,mask6n7,shrunk_radius,diameter_even,error,jump_vector:word=LocalStk
  357.  
  358.     push bp
  359.     mov  bp, sp
  360.     sub  sp, LocalStk
  361.     push si
  362.     push di
  363.  
  364.     cld                    ; strings march forward
  365.  
  366. ; this first part is identical to the other function --
  367. ; the only differences, in fact, are in the drawing and moving around
  368.  
  369. ; find starting locations of plots 2, 3, 6, and 7
  370.     mov di, _ScrnLogicalByteWidth
  371.     xor dx, dx
  372.  
  373.     mov ax, Diameter    ; find vertical midpoint
  374.     dec ax
  375.     shr ax, 1
  376.     adc dx, 0           ; remember if it's rounded
  377.     mov shrunk_radius, ax ; radius, rounded down for adding
  378.     mov diameter_even, dx ; (diameter - 1) & 1, effectively
  379.     add ax, Top
  380.     mul di              ; vertical midpoint in bytes
  381.     add ax, ScreenOffs
  382.  
  383.     mov bx, Left
  384.     mov cx, bx          ; save for later
  385.     mov si, bx
  386.     shr si, 2
  387.     add si, ax
  388.     mov offset6, si
  389.     and bx, 3           ; column of left side
  390.     mov bl, ColumnMask[bx]
  391.     mov mask6n7, bx
  392.  
  393.     add cx, Diameter
  394.     dec cx
  395.     mov bx, cx
  396.     shr cx, 2
  397.     add cx, ax
  398.     mov offset2, cx
  399.     and bx, 3           ; column of right side
  400.     mov bl, ColumnMask[bx]
  401.     mov mask2n3, bx
  402.  
  403.     cmp diameter_even, 1
  404.     jne @@MiddlePlotsOverlap
  405.     add si, di
  406.     add cx, di
  407. @@MiddlePlotsOverlap:
  408.     mov offset7, si
  409.     mov offset3, cx
  410.  
  411. ; starting locations of 0, 1, 4, and 5
  412.     mov bx, Left
  413.     add bx, shrunk_radius ; find horizontal midpoint
  414.  
  415.     mov ax, Top         ; top in bytes
  416.     mul di
  417.     add ax, ScreenOffs
  418.     mov si, ax
  419.  
  420.     mov ax, Diameter    ; bottom in bytes
  421.     dec ax
  422.     mul di
  423.     add ax, si
  424.  
  425.     mov di, bx          ; horizontal midpoint in bytes
  426.     shr di, 2
  427.     add si, di             ; top midpoint in bytes
  428.     mov offset4, si
  429.     add di, ax             ; bottom midpoint in bytes
  430.     mov offset5, di
  431.     and bx, 3           ; column of horizontal midpoint
  432.     mov bl, ColumnMask[bx]
  433.     mov mask4n5, bx
  434.  
  435.     cmp diameter_even, 1
  436.     jne @@TopAndBottomPlotsOverlap
  437.     rol bl, 1
  438.     jnc @@TopAndBottomPlotsOverlap
  439.     inc si
  440.     inc di
  441. @@TopAndBottomPlotsOverlap:
  442.     mov offset0, si
  443.     mov offset1, di
  444.     mov mask0n1, bx
  445.  
  446. ; we've got our eight plots in their starting positions, so
  447. ; it's time to sort out the registers
  448.     mov bx, _ScrnLogicalByteWidth
  449.  
  450.     mov dx, SCREEN_SEG
  451.     mov es, dx
  452.  
  453.     mov dx, SC_INDEX    ; set VGA to accept column masks
  454.     mov al, MAP_MASK
  455.     out dx, al
  456.     inc dx              ; gun the engine...
  457.  
  458.     mov si, Diameter    ; initial y is radius -- 2 #s per pixel
  459.     inc si
  460.  
  461.     mov cx, si
  462.     neg cx
  463.     add cx, 2
  464.     mov error, cx        ; error = -y + one pixel since we're a step ahead
  465.  
  466.     xor cx, cx          ; initial x = 0
  467.     mov ah, byte ptr Color
  468.     jmp @@FilledCircleCalc ; let's actually put something on the screen!
  469.  
  470.  
  471. ; plotting is completely different from in the other function (naturally)
  472. @@PlotLines:
  473.     push cx                ; we'll need cx for string stores
  474.  
  475. ; draw x-major horz. lines, from plot 4 to plot 0 and from plot 5 to plot 1
  476.     mov di, mask0n1
  477.     and di, 0000fh        ; we only want the lower nybble for the mask table
  478.     mov al, RightMaskTable[di]
  479.     mov di, offset0        ; left and right offsets the same?
  480.     cmp di, offset4
  481.     jne @@PlotXMajorNontrivial ; try and say this one 10 times fast!
  482.     mov di, mask4n5
  483.     and di, 0000fh
  484.     and al, LeftMaskTable[di] ; intersection of left & right masks
  485.     out dx, al            ; set mask
  486.     mov di, offset4
  487.     mov es:[di], ah
  488.     mov di, offset5
  489.     mov es:[di], ah
  490.     jmp @@PlotYMajor
  491. @@PlotXMajorNontrivial:
  492.     out dx, al          ; draw right edge
  493.     mov es:[di], ah
  494.     mov di, offset1
  495.     mov es:[di], ah
  496.  
  497.     mov di, mask4n5        ; draw left edge
  498.     and di, 0000fh
  499.     mov al, LeftMaskTable[di]
  500.     out dx, al
  501.     mov di, offset4
  502.     mov es:[di], ah
  503.     mov di, offset5
  504.     mov es:[di], ah
  505.  
  506.     mov al, 0ffh        ; set mask for middle chunks
  507.     out dx, al
  508.     mov al, ah            ; ready to store two pixels at a time
  509.     inc di                ; move string start past left edge
  510.     mov cx, offset1        ; store line from plot 5 to plot 1, exclusive
  511.     sub cx, di            ; width of section in bytes
  512.     push cx
  513.     shr cx, 1            ; draw midsection eight pixels at a time
  514.     rep stosw
  515.     adc cx, 0            ; draw last four pixels, if such there are
  516.     rep stosb
  517.  
  518.     mov di, offset4        ; draw line from plot 4 to plot 0
  519.     inc di                ; move past left edge
  520.     pop cx
  521.     shr cx, 1
  522.     rep stosw
  523.     adc cx, 0
  524.     rep stosb
  525.  
  526. @@PlotYMajor:
  527. ; draw y-major horz. lines, from plot 6 to plot 2 and from plot 7 to plot 3
  528.     mov di, mask2n3
  529.     and di, 0000fh        ; we only want the lower nybble for the mask table
  530.     mov al, RightMaskTable[di]
  531.     mov di, offset2        ; left and right offsets the same?
  532.     cmp di, offset6
  533.     jne @@PlotYMajorNontrivial ; try and say this one 10 times fast!
  534.     mov di, mask6n7
  535.     and di, 0000fh
  536.     and al, LeftMaskTable[di] ; intersection of left & right masks
  537.     out dx, al            ; set mask
  538.     mov di, offset6
  539.     mov es:[di], ah
  540.     mov di, offset7
  541.     mov es:[di], ah
  542.     jmp @@ClimaxOfPlot
  543. @@PlotYMajorNontrivial:
  544.     out dx, al          ; draw right edge
  545.     mov es:[di], ah
  546.     mov di, offset3
  547.     mov es:[di], ah
  548.  
  549.     mov di, mask6n7        ; draw left edge
  550.     and di, 0000fh
  551.     mov al, LeftMaskTable[di]
  552.     out dx, al
  553.     mov di, offset6
  554.     mov es:[di], ah
  555.     mov di, offset7
  556.     mov es:[di], ah
  557.  
  558.     mov al, 0ffh        ; set mask for middle chunks
  559.     out dx, al
  560.     mov al, ah            ; ready to store two pixels at a time
  561.  
  562.     inc di                ; move string start past left edge
  563.     mov cx, offset3        ; draw line from plot 7 to plot 3, exclusive
  564.     sub cx, di            ; width of section in bytes
  565.     push cx
  566.     shr cx, 1            ; store midsection
  567.     rep stosw
  568.     adc cx, 0
  569.     rep stosb
  570.  
  571.     mov di, offset6        ; draw line from plot 6 to plot 2
  572.     inc di                ; move past left edge
  573.     pop cx
  574.     shr cx, 1
  575.     rep stosw
  576.     adc cx, 0
  577.     rep stosb
  578.  
  579. @@ClimaxOfPlot:
  580.     pop cx
  581.     jmp [jump_vector]    ; either @@Advance or @@NoAdvance
  582.  
  583.  
  584. ; unlike their counterparts in the other function, these do not draw --
  585. ; they only move the eight pointers
  586.  
  587. ; move the x-major plots horizontally and the y-major plots vertically
  588. @@NoAdvance:
  589.     mov al, byte ptr mask0n1 ; advance left x-major plots
  590.     mov di, offset0
  591.     rol al, 1           ; advance 0 right
  592.     mov byte ptr mask0n1, al
  593.     adc di, 0
  594.     mov offset0, di
  595.     mov di, offset1
  596.     ror al, 1           ; what was that bit again?
  597.     adc di, 0           ; advance 1 right
  598.     mov offset1, di
  599.  
  600.     mov al, byte ptr mask4n5 ; advance left x-major plots
  601.     mov di, offset4
  602.     ror al, 1
  603.     mov byte ptr mask4n5, al
  604.     sbb di, 0
  605.     mov offset4, di
  606.     mov di, offset5
  607.     rol al, 1
  608.     sbb di, 0
  609.     mov offset5, di
  610.  
  611.     mov al, byte ptr mask2n3
  612.     mov di, offset2
  613.     sub di, bx          ; advance 2 up
  614.     mov offset2, di
  615.     mov di, offset3
  616.     add di, bx          ; advance 3 down
  617.     mov offset3, di
  618.  
  619.     mov al, byte ptr mask6n7
  620.     mov di, offset6
  621.     sub di, bx
  622.     mov offset6, di
  623.     mov di, offset7
  624.     add di, bx
  625.     mov offset7, di
  626.  
  627.     jmp @@FilledCircleCalc
  628.  
  629. ; move all plots diagonally
  630. @@Advance:
  631.     mov al, byte ptr mask0n1
  632.     mov di, offset0
  633.     rol al, 1           ; advance 0 right and down
  634.     mov byte ptr mask0n1, al
  635.     adc di, bx
  636.     mov offset0, di
  637.     mov di, offset1
  638.     ror al, 1           ; what was that bit again?
  639.     adc di, 0           ; advance 1 right and up
  640.     sub di, bx
  641.     mov offset1, di
  642.  
  643.     mov al, byte ptr mask2n3
  644.     mov di, offset2
  645.     ror al, 1           ; advance 2 up and left
  646.     mov byte ptr mask2n3, al
  647.     sbb di, bx
  648.     mov offset2, di
  649.     mov di, offset3
  650.     rol al, 1
  651.     sbb di, 0           ; advance 3 down and left
  652.     add di, bx
  653.     mov offset3, di
  654.  
  655.     mov al, byte ptr mask4n5
  656.     mov di, offset4
  657.     ror al, 1
  658.     mov byte ptr mask4n5, al
  659.     sbb di, 0
  660.     add di, bx
  661.     mov offset4, di
  662.     mov di, offset5
  663.     rol al, 1
  664.     sbb di, bx
  665.     mov offset5, di
  666.  
  667.     mov al, byte ptr mask6n7
  668.     mov di, offset6
  669.     rol al, 1
  670.     mov byte ptr mask6n7, al
  671.     adc di, 0
  672.     sub di, bx
  673.     mov offset6, di
  674.     mov di, offset7
  675.     ror al, 1
  676.     adc di, bx
  677.     mov offset7, di
  678.  
  679. ; do you realize the entire function has been set up around this little jot?
  680. ; keep in mind that radii values are 2 per pixel
  681. @@FilledCircleCalc:
  682.     add cx, 2           ; x += 1
  683.     mov di, error
  684.     add di, cx          ; error += (2 * x) + 1
  685.     inc di
  686.     jl @@FilledCircleNoError
  687.     cmp cx, si          ; x > y?
  688.     ja @@FleeFlyFlowFum
  689.     sub si, 2           ; y -= 1
  690.     sub di, si          ; error -= (2 * y)
  691.     mov error, di
  692.     mov jump_vector, offset @@Advance
  693.     jmp @@PlotLines
  694. @@FilledCircleNoError:
  695.     mov error, di
  696.     mov jump_vector, offset @@NoAdvance
  697.     jmp @@PlotLines
  698.  
  699. @@FleeFlyFlowFum:
  700.     pop di
  701.     pop si
  702.     mov sp,bp
  703.     pop bp
  704.  
  705.     ret
  706.  
  707. _x_filled_circle endp
  708.  
  709.     end
  710.  
  711.